#pragma once

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace SbCli;

namespace SbCli
{
	namespace Qgp
	{
		//
		[Flags]
		public enum class Clearance
		{
			Depth = 1,
			Stencil = 2,
			Render = 3,
		};

		//
		public enum class TM
		{
			World,
			View,
			Proj,
			Tex0,
			Tex1,
			Tex2,
			Tex3,
			Tex4,
			Tex5,
			Tex6,
			Tex7,
		};

		//
		public enum class ColorFormat
		{
			None,

			B8_L,
			B16_L,

			B16_RGB,
			B16_RGBA,

			B32_RGB,
			B32_RGBA,
			B32_BGR,
			B32_BGRA,

			F16_R,
			F64_BGRA,

			F32_R,
			F128_BGRA,

			DXT1,
			DXT2,
			DXT3,
			DXT4,
			DXT5,
		};

		//
		[Flags]
		public enum class ColorFlag
		{
			None = 0,
			Alpha = 0x0001,
			Compress = 0x0002,
			Float = 0x0004,
			BGR = 0x0008,
		};

		//
		[Flags]
		public enum class ColorMask
		{
			Red = 1,
			Green = 2,
			Blue = 4,
			Alpha = 8,
		};

		//
		public enum class Topology
		{
			PointList,
			LineList,
			LineStrip,
			TriList,
			TriStrip,
		};

		//
		public enum class CompareOp
		{
			Never,
			LQ,
			EQ,
			LEQ,
			GR,
			NEQ,
			GEQ,
			Always,
		};

		//
		public enum class StencilOp
		{
			Keep,
			Zero,
			Replace,
			SatInc,
			SatDec,
			Invert,
			Increment,
			Decrement,
		};

		//
		public enum class TextureFilter
		{
			Point,
			Linear,
			MagMinMipPoint,
			MagMinPoint_MipLinear,
			MagPoint_MinLinear_MipPoint,
			MagPoint_MinMipLinear,
			Mag_Linear_MinMipPoint,
			MagLinear_MinPoint_MipLinear,
			MagMinLinear_MipPoint,
			MagMinMipLinear,
			Anisotropic,
		};

		// 
		public enum class TextureAddress
		{
			Wrap,
			Mirror,
			Clamp,
			Border,
			Once,
		};

		//
		public enum class TriangleFill
		{
			Point,
			Wire,
			Solid,
		};

		//
		public enum class CullMode
		{
			None,
			Front,
			Back,
		};

		// 
		public enum class BlendOp
		{
			Add,
			Sub,
			Rsub,
			Min,
			Max,
		};

		//
		public enum class BlendFactor
		{
			Zero,
			One,
			SC,
			SCInv,
			SA,
			SAInv,
			DA,
			DAInv,
			DC,
			DCInv,
			SAS,
		};

		//
		public enum class DloUsage
		{
			Position,
			Color,
			Weight,
			Index,
			Normal,
			Texture,
			Tangent,
			Binormal,
		};

		// 
		public enum class DloType
		{
			Float1,
			Float2,
			Float3,
			Float4,
			Uint1,
			Uint2,
			Uint3,
			Uint4,
			Half2,
			Half4,
			Byte2,
			Byte4,
			Ushort2,
			Ushort4,
			UintColor,
		};

		//
		public enum class ResourceType
		{
			Texture,
			Rasz,
			Blnd,
			Splr,
			Shader,
			Buffer,
			Layout,
		};

		//
		public enum class MaxStages
		{
			Texture = 8,
			OffTexture = 4,
			Vertex = 4,
		};

		//
		[Flags]
		public enum class ResourceFlag
		{
			None = 0,
			Dynamic = 0x0001,
			Local = 0x0002,
			Stream = 0x0004,

			//
			BGRA = 0x100
		};

		//
		public enum class EnterFlag
		{
			None = 0,
			Read = 0x001,
			Write = 0x0002,
			ReadWrite = 0x0001 | 0x0002,
		};

		//////////////////////////////////////////////////////////////////////////

		//
		public value struct ViewPort
		{
		public:
			Point2 Location;
			Point2 Size;
			Vec2 Depth;
			float Aspect;
		};

		//
		public ref class ColorSupp sealed
		{
		private:
			ColorSupp() {}

		public:
			static bool TestAlpha(ColorFormat fmt)
			{
				return qgColorSupp::TestAlpha((qgColorFormat)fmt);
			}

			static kuint UnsafePackPixel(ColorFormat fmt, kbyte r, kbyte g, kbyte b, kbyte a)
			{
				return qgColorSupp::UnsafePackPixel((qgColorFormat)fmt, r, g, b, a);
			}
		};

		//////////////////////////////////////////////////////////////////////////

		
		//////////////////////////////////////////////////////////////////////////

		//
		[StructLayout(LayoutKind::Sequential)]
		[Serializable]
		public value struct ParamProj
		{
		public:
			float FOV;
			float Aspect;
			Vec2 Z;
		};

		//
		[StructLayout(LayoutKind::Sequential)]
		[Serializable]
		public value struct ParamView
		{
		public:
			Vec3 At;
			Vec3 Up;
			Vec3 Ahead;
		};

		//
		[StructLayout(LayoutKind::Sequential)]
		[Serializable]
		public value struct ParamCamera
		{
		public:
			Mat4 Proj;
			Mat4 View;
			Mat4 Invv;
			Mat4 ViewProj;
		};
	}
}
